import os, time
from perf_decorater import time_decorater
class OPBASE():
    def __init__(self, ssh_client, server, port, bg_port, confpath, name='base'):
        self.name = name
        self.server = server
        self.port = port
        self.bg_port = []
        if bg_port and bg_port[0] != '':
            self.bg_port = [int(p) for p in bg_port]
        self.confpath = confpath
        self.ssh_client = ssh_client
        self.sub_dir = 'multi_case'

    def delete_file(self, filename=None):
        if filename:
            self.ssh_client.exec_command('rm -rf %s/%s' %(self.confpath, filename))
        else:
            self.ssh_client.exec_command('rm -rf %s' % (self.confpath))

    @time_decorater
    def upload_file(self, filename):
        self.ssh_client.exec_command('mkdir -p ' +  self.confpath)
        self.ssh_client.put(os.path.join(self.confpath, filename), os.path.join(self.confpath, filename))
        self.ssh_client.chdir(self.confpath)
        self.ssh_client.exec_command('tar zxvf %s -C %s' % (os.path.join(self.confpath, filename), self.confpath))

    def download_file(self, path, filename):
        pid = self.get_pid()
        perf_path = self._get_performance_path()
        self.ssh_client.get(perf_path + '/' + filename, path +'/' + filename + str(pid))

    def print_performance_data(self, filename):
        perf_path = self._get_performance_path()
        return self.ssh_client.exec_command("cat %s/%s" % (perf_path, filename))

    def download_performance_file(self, path):
        self.download_file(path, "dnsperf_stat.static");
        self.download_file(path, "dnsperf_stat.perf");
    
    def _get_performance_path(self):
        return os.path.join(self.confpath, 'performance_test')
        
    def start_performance_stat(self):
        pid = self.get_pid()
        perf_path = self._get_performance_path()
        self.ssh_client.chmod(os.path.join(perf_path, 'dnsperf_stat_begin.sh'), 456)
        self.ssh_client.chmod(os.path.join(perf_path, 'dnsperf_stat_stop.sh'), 456)

        exec_path = os.path.join(perf_path, 'py_call_stat.py') 
        self.ssh_client.chmod(exec_path, 456)

        cmd = '%s -p %d -d %s > /dev/null < /dev/null 2>&1' % (exec_path, pid[0], perf_path )
        print '%s:%s' % (self.name, cmd)
        self.ssh_client.exec_command(cmd, True)

    def stop_performance_stat(self):
        perf_path = self._get_performance_path()
        cmd = '%s -d %s' % (os.path.join(perf_path, 'dnsperf_stat_stop.sh'), perf_path)
        print '%s:%s' % (self.name, cmd)
        self.ssh_client.exec_command(cmd, True)

    def before_start_server(self, **opts):
        pass
    def check_server(self, checktime):
        print '%s:checking server start......, please wait at most %s seconds' % (self.name, checktime)
        return True

    def get_pid(self):
        servername = self.name
        if servername == 'bind':
            servername = 'named'
        if self.bg_port:
            path = [self.confpath + '/' + self.sub_dir + '/' + str(port) for port in self.bg_port]
        else:
            path = [self.confpath]

        pid = []
        for confpath in path:
            cmd = 'cat %s/etc/%s.pid' % (confpath, servername)
            pidinfo = self.ssh_client.exec_command(cmd)
            if pidinfo:
                pid.append(int(pidinfo[0].strip('\n')))

        return pid

    def kill_server(self):
        pidlist = self.get_pid()
        if not pidlist:
            return
        for pid in pidlist:
            cmd = 'kill -9 %d' % pid
            self.ssh_client.exec_command(cmd)
            cmd = "ps axu|awk '/%s/&&/%d/&&!/awk/{print $4}'" % (self.name, pid)
            for i in range(10):
                result = self.ssh_client.exec_command(cmd)
                if not result:
                    break
                else:
                    time.sleep(i)

class OPBIND(OPBASE):
     def __init__(self, ssh_client, server, port, bg_port, confpath):
         OPBASE.__init__(self, ssh_client, server, port, bg_port, confpath, 'bind')

     @time_decorater
     def start_server(self, threadnum, **args):
         if self.bg_port:
             sub_dir = self.sub_dir
             confpath = self.confpath
             self.ssh_client.exec_command("mkdir -p " + os.path.join(confpath, sub_dir))
             for port in self.bg_port:
                 self.ssh_client.exec_command("mkdir -p %s/%s/%d" % (confpath, sub_dir, port))
                 cmd = "cp -r %s/etc %s/data %s/log %s/%s/%d" % (confpath, confpath, confpath, confpath, sub_dir, port)
                 print "%s:%s" % (self.name, cmd)
                 self.ssh_client.exec_command(cmd)
                 cmd = "sed -i '/listen-on/s;%d;%d;' %s/%s/%d/etc/named.conf" % (self.port, port, confpath, sub_dir, port)
                 print "%s:%s" % (self.name, cmd)
                 self.ssh_client.exec_command(cmd)
                 cmd = "sed -i 's;%s;%s;' %s/%s/%d/etc/named.conf" % (confpath, confpath+'/'+sub_dir+'/'+str(port), confpath, sub_dir, port)
                 print "%s:%s" % (self.name, cmd)
                 self.ssh_client.exec_command(cmd)
                 cmd = 'named -c %s/%s/%d/etc/named.conf -n %d' % (confpath, sub_dir, port, threadnum)
                 print "%s:%s" % (self.name, cmd)
                 self.ssh_client.exec_command(cmd)
         else:
             cmd = 'named -c %s/etc/named.conf -n %d' % (self.confpath, threadnum)
             self.ssh_client.exec_command(cmd)

class OPMAPLE(OPBASE):
     def __init__(self, ssh_client, server, port, bg_port, confpath):
         OPBASE.__init__(self, ssh_client, server, port, bg_port, confpath, 'maple')

     @time_decorater
     def before_start_server(self, **opts):
         if 'viewnum' not in opts :
             opts['viewnum'] = 0
         if 'viewprefix' not in opts:
             opts['viewprefix'] = 'view'
         confpath = self.confpath
         cmd = 'python %s/etc/add_zone_to_conf.py -c %s -p %s -v %d -z %d ' % ( confpath, confpath +'/etc/maple.xml', confpath +'/data', opts['viewnum'], opts['zonenum'])

         result = self.ssh_client.exec_command(cmd)
         for ret in result:
             print '<<<<<<', ret,
     @time_decorater
     def start_server(self, threadnum, **args):
         cmd = 'maple -c %s/etc/maple.xml -u %d -t %d' % (self.confpath, threadnum, threadnum)
         self.ssh_client.exec_command(cmd)

     @time_decorater
     def check_server(self, checktime, **args):
         print '%s:checking server start, please wait at most %s seconds' % (self.name, checktime)
         pid = self.get_pid()
         cmd = "ps axu|awk '/%s/&&/%d/&&!/awk/{print $4}'" % (self.name, pid[0])
         print "%s:%s" % (self.name, cmd)
         ok_count = 0;
         last_mem = 0;
         for i in range(checktime):
             result = self.ssh_client.exec_command(cmd)
             if result:
                 mem_ratio = float(result[0].strip('\n'))
                 print "mem ratio:", mem_ratio
                 if mem_ratio > last_mem:
                    last_mem = mem_ratio
                 else:
                    ok_count += 1
                 if ok_count >= 2:
                    print "%s: server start up and loads all zone datas" % self.name
                    break
             time.sleep(2)
         if i >= checktime - 1:
             return False
         return True
